/*
 * @Author: NJ_1098 xiabaoxin
 * @Date: 2025-02-11 16:17:45
 * @LastEditors: NJ_1098 xiabaoxin
 * @LastEditTime: 2025-02-17 11:19:56
 * @Description: 用户中间件
 */
const jwt = require("jsonwebtoken");
const { JWT_KEY } = require("../config/config.default");
const BaseMiddle = require("./base.middle");
const UserService = require("../service/user.service");
const CommonUtils = require("../utils/common");
const {
  userFormatterError,
  userExitedError,
  userTokenExpiredError,
  userTokenInvalidError,
  userLoginError,
  systemError,
  registerLackError,
  codeError,
  optionError,
} = require("../constant/index.js");
const baseMiddleInstance = new BaseMiddle();

class UserMiddleware {
  /**
   * @author: NJ_1098 xiabaoxin
   * @description: 验证注册信息必填项
   * @param {*} ctx
   * @param {*} next
   * @return {*}
   */
  static async registerValidate(ctx, next) {
    if (!(await baseMiddleInstance.optionValidate(ctx))) {
      return;
    }
    const { account, password, code, iv } = ctx.request.body;
    if (!account || !password || !code || !iv) {
      ctx.app.emit("error", userFormatterError, ctx);
      return;
    }
    await next();
  }

  /**
   * @author: NJ_1098 xiabaoxin
   * @description: 验证码校验
   * @param {*} ctx
   * @param {*} next
   * @return {*}
   */
  static async codeValidate(ctx, next) {
    const { code, iv } = ctx.request.body;
    const realCode = CommonUtils.decrypt(iv);
    if (code !== realCode) {
      ctx.app.emit("error", codeError, ctx);
      return;
    }
    await next();
  }

  /**
   * 验证微信新增用户信息的合法性，是否存在必填字段
   * @param {*} ctx
   * @param {*} next
   * @returns
   */
  static async wxAddValidate(ctx, next) {
    if (!(await baseMiddleInstance.optionValidate(ctx))) {
      return;
    }
    const { openid, wname } = ctx.request.body;
    if (!openid || !wname) {
      ctx.app.emit("error", registerLackError, ctx);
      return;
    }
    await next();
  }

  /**
   * @author: NJ_1098 xiabaoxin
   * @description: 验证更新用户信息合法性，是否存在更新字段
   * @param {*} ctx
   * @param {*} next
   * @return {*}
   */
  static async updateValidate(ctx, next) {
    if (!(await baseMiddleInstance.optionValidate(ctx))) {
      return;
    }
    await next();
  }

  /**
   * @author: NJ_1098 xiabaoxin
   * @description: 删除用户信息校验，查看是否传入uid集合
   * @return {*}
   */
  static async deleteValidate(ctx, next) {
    if (!(await baseMiddleInstance.optionValidate(ctx))) {
      return;
    }
    const { uids } = ctx.request.body;
    if (!uids || uids.length === 0) {
      ctx.app.emit("error", optionError, ctx);
      return;
    }
    await next();
  }

  /**
   * 验证用户信息的合理性，是否已存在用户
   * @param {*} ctx
   * @param {*} next
   * @returns
   */
  static async userExitValidate(ctx, next) {
    try {
      const { account, password, openid } = ctx.request.body;
      let tempPwd = password;
      if (password) {
        tempPwd = CommonUtils.encrypt(tempPwd);
      }
      if (
        await UserService.getUserInfo({ account, password: tempPwd, openid })
      ) {
        ctx.app.emit("error", userExitedError, ctx);
        return;
      }
      await next();
    } catch (err) {
      console.log(err);
      systemError.data = err.toString();
      ctx.app.emit("error", optionError, ctx);
    }
  }

  /**
   * 验证用户微信登录信息
   * @param {*} ctx
   * @param {*} next
   * @returns
   */
  static async wxLoginValidate(ctx, next) {
    if (!(await baseMiddleInstance.optionValidate(ctx))) {
      return;
    }
    const { openid } = ctx.request.body;
    if (!openid) {
      ctx.app.emit("error", userLoginError, ctx);
      return;
    }
    await next();
  }

  /**
   * 验证用户token
   * @param {*} ctx
   * @param {*} next
   * @returns
   */
  static async verifyToken(ctx, next) {
    try {
      const { authorization } = ctx.request.header;
      const userInfo = jwt.verify(authorization, JWT_KEY);
      ctx.state.userInfo = userInfo;
      await next();
    } catch (err) {
      switch (err.name) {
        case "TokenExpiredError":
          console.error("token已过期", err);
          ctx.app.emit("error", userTokenExpiredError, ctx);
          return;
        case "JsonWebTokenError":
          console.error("无效的token", err);
          ctx.app.emit("error", userTokenInvalidError, ctx);
          return;
        default:
          return;
      }
    }
  }
}

module.exports = UserMiddleware;
